home *** CD-ROM | disk | FTP | other *** search
- /*
- ** CSPPC233Fix_wos.c
- **
- ** An Instruction Access Exception handler, which tries to recover from
- ** a hardware bug on CSPPC/233 cards by fixing the trashed LR register.
- **
- ** Written by Frank Wille <frank@phoenix.owl.de>.
- ** This code is PUBLIC DOMAIN.
- **
- */
-
- #include <stdio.h>
- #include <time.h>
- #include <dos/dos.h>
- #include <powerpc/powerpc.h>
- #include <powerpc/tasksPPC.h>
- #include <clib/powerpc_protos.h>
-
-
- static int sigExcept; /* exception notification signal */
- static struct EXCContext EC; /* copy of exception context */
- static struct TaskPPC *thisTask; /* this task */
- static struct TaskPPC *excTask; /* excepting task */
-
- ULONG IAccessException(struct EXCContext *);
-
- /* This line is vbcc-specific, the rest should be portable (to
- Storm-C, for example). Although I doubt that gcc-WarpOS would
- work, because the exception handler should be PowerOpen-ABI). */
- ULONG r2(void) = "\tmr\tr3,r2"; /* gets TOC-pointer */
-
-
-
- main()
- {
- static ULONG cnt=0;
- struct TagItem ti[8];
- void *xhdl;
- ULONG sigmsk;
-
- if ((sigExcept = AllocSignalPPC(-1)) >= 0) {
- thisTask = FindTaskPPC(NULL);
-
- /* install a global handler for Instruction Access Exceptions */
- ti[0].ti_Tag = EXCATTR_CODE;
- ti[0].ti_Data = (ULONG)IAccessException;
- ti[1].ti_Tag = EXCATTR_DATA;
- ti[1].ti_Data = r2();
- ti[2].ti_Tag = EXCATTR_EXCID;
- ti[2].ti_Data = EXCF_IACCESS;
- ti[3].ti_Tag = EXCATTR_FLAGS;
- ti[3].ti_Data = EXCF_GLOBAL | EXCF_LARGECONTEXT;
- ti[4].ti_Tag = EXCATTR_PRI;
- ti[4].ti_Data = 127;
- ti[5].ti_Tag = EXCATTR_NAME;
- ti[5].ti_Data = (ULONG)"Trashed-LR bug fix for CSPPC/233";
- ti[6].ti_Tag = TAG_DONE;
-
- if (xhdl = SetExcHandler(ti)) {
- printf("Instruction Access exception handler installed.\n"
- "Press CTRL-C to quit.\n");
- do {
- /* wait for an exception or the signal to quit (CTRL-C) */
- sigmsk = WaitPPC((1L<<sigExcept) | (1L<<SIGBREAKB_CTRL_C));
-
- if (sigmsk & (1L<<sigExcept)) {
- /* print exception info */
- time_t tim;
- char buf[32];
-
- time(&tim);
- strftime(buf,sizeof(buf),"%x",localtime(&tim));
- printf("**(%lu) %s Trashed LR: 0x%08lx Task: %08lx (%s)\n",
- ++cnt,buf,EC.ec_LR,(ULONG)excTask,
- excTask->tp_Task.tc_Node.ln_Name);
- }
- }
- while (!(sigmsk & (1L<<SIGBREAKB_CTRL_C)));
- RemExcHandler(xhdl);
- }
-
- FreeSignalPPC(sigExcept);
- }
- }
-
-
- ULONG IAccessException(struct EXCContext *ec)
- {
- /* first check if this exception was caused by a trashed LR register */
- if (ec->ec_UPC.ec_SRR0 == ec->ec_LR && (ec->ec_LR & 0xf0000000) != 0) {
- CopyMemPPC(ec,&EC,sizeof(struct EXCContext)); /* save exception ctxt. */
- ec->ec_UPC.ec_SRR0 &= 0x0fffffff; /* fix PC and LR */
- ec->ec_LR &= 0x0fffffff;
- excTask = FindTaskPPC(NULL);
- SignalPPC(thisTask,1L<<sigExcept); /* show exception info */
- return (EXCRETURN_ABORT); /* retry instruction access */
- }
- return (EXCRETURN_NORMAL);
- }
-